<?php
abstract class content_Mapper {
    protected static $PDO;
    function __construct() {        
        if ( ! isset(self::$PDO) ) {

            if ( is_null(DSN) ) {
            throw new Exception( "No DSN" );
            }
            self::$PDO = DB_Link::getInstance();
            self::$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        }
    }
    function findById( $id ) {        
        $this->selectStmt()->execute(array($id));        
        $array = $this->selectStmt()->fetch();        
        $this->selectStmt()->closeCursor( );        
        if ( ! is_array( $array ) ) { return null; }        
        $object = $this->createObject( $array );        
        return $object;
    }

    

    function createObject( $array ) {
        $obj = $this->doCreateObject( $array );        
        return $obj;
    }
    function insert( $obj ) {
        return $this->doInsert( $obj );
    }
    function save($object){        
        if($object->getId() < 1){
            return $this->insert($object);
        } else {
           return $this->update($object);
        }
    }
    abstract function update($object );
    protected abstract function doCreateObject( array $array );
    protected abstract function doInsert( $object );
    protected abstract function targetClass();
    protected abstract function selectStmt();
}




abstract class content_Mapper_Collection implements Iterator {
    protected $mapper;
    protected $total = 0;
    protected $raw = array();
    private $result;
    private $pointer = 0;
    private $objects = array();
    function __construct( array $raw=null, content_Mapper $mapper=null ) {
        if ( ! is_null( $raw ) && ! is_null( $mapper ) ) {
        $this->raw = $raw;
        $this->total = count( $raw );
        }
        $this->mapper = $mapper;
    }
    function add( content $object ) {
        $class = $this->targetClass();
        if ( ! ($object instanceof $class ) ) {
        throw new Exception("This is a {$class} collection");
        }
        $this->notifyAccess();
        $this->objects[$this->total] = $object;
        $this->total++;
    }
    abstract function targetClass();
    protected function notifyAccess() {
    // deliberately left blank!
    }
    private function getRow( $num ) {
        $this->notifyAccess();
        if ( $num >= $this->total || $num < 0 ) {
         return null;
        }
        if ( isset( $this->objects[$num]) ) {
            return $this->objects[$num];
        }
        if ( isset( $this->raw[$num] ) ) {
            $this->objects[$num]=$this->mapper->createObject( $this->raw[$num] );
            return $this->objects[$num];
        }
    }
    public function rewind() {
        $this->pointer = 0;
    }
    public function current() {
        return $this->getRow( $this->pointer );
    }
    public function key() {
        return $this->pointer;
    }
    public function next() {
        $row = $this->getRow( $this->pointer );
        if ( $row ) { $this->pointer++; }
        return $row;
    }
    public function valid() {
        return ( ! is_null( $this->current() ) );
    }
}
?>
